Skip to content

feat: add public profile Open Graph previews#400

Open
amritbej wants to merge 4 commits into
Dev-Card:mainfrom
amritbej:feature/og-meta-tags
Open

feat: add public profile Open Graph previews#400
amritbej wants to merge 4 commits into
Dev-Card:mainfrom
amritbej:feature/og-meta-tags

Conversation

@amritbej

@amritbej amritbej commented May 29, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Added a cached backend OG image endpoint for public profiles.
  • Generated a server-side PNG preview with avatar/initials, display name, bio, and platform badges.
  • Added canonical, Open Graph, and Twitter Card metadata to the public profile page.
  • Added focused backend tests for OG image generation and Redis cache behavior.

Closes #33

Validation

  • pnpm --filter @devcard/backend exec eslint src/routes/public.ts src/utils/og-image.ts src/__tests__/public.test.ts
  • pnpm --filter @devcard/backend exec vitest run src/__tests__/public.test.ts
  • pnpm --filter @devcard/web check

Note

pnpm --filter @devcard/backend build is currently blocked by existing unrelated TypeScript issues in backend test files.

@amritbej

Copy link
Copy Markdown
Contributor Author

@Harxhit ,
please check the pr i have linked

@Harxhit Harxhit added the gssoc:approved Required label for every approved PR. Gives the base +50 points and enables contribution tracking. label May 30, 2026
@amritbej

amritbej commented Jun 2, 2026

Copy link
Copy Markdown
Contributor Author

@Harxhit , please check the pr i have linked

@ShantKhatri please check it .

@amritbej amritbej force-pushed the feature/og-meta-tags branch from ccae586 to ece9eea Compare June 5, 2026 12:52
@vercel

vercel Bot commented Jun 5, 2026

Copy link
Copy Markdown

Someone is attempting to deploy a commit to the Prashantkumar Khatri's projects Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions

github-actions Bot commented Jun 5, 2026

Copy link
Copy Markdown

CI — Checks Failed

Backend — FAIL

Check Result
Lint FAIL
Test PASS
Typecheck PASS

Mobile — SKIP

Check Result
Lint -
Test -

Web — PASS

Check Result
Build PASS

Last updated: Thu, 18 Jun 2026 11:25:14 GMT

@amritbej

amritbej commented Jun 5, 2026

Copy link
Copy Markdown
Contributor Author

@ShantKhatri , please review it .

@ShantKhatri

Copy link
Copy Markdown
Collaborator

@ShantKhatri , please review it .

Hi, checks are failing.

@Harxhit

Harxhit commented Jun 5, 2026

Copy link
Copy Markdown
Collaborator

@ShantKhatri , please review it .

Hi, checks are failing.

Please allow me some time.

@amritbej

amritbej commented Jun 9, 2026

Copy link
Copy Markdown
Contributor Author

@Harxhit ,
please check it

Signed-off-by: amritbej.sh <amritbej750@gmail.com>
@amritbej

Copy link
Copy Markdown
Contributor Author

@Harxhit ,
please review it it's been 2 weeks i have opened the pr and tell if anything wrong ..

@Harxhit Harxhit left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: this branch does not build

The headline issue is that the merge of main into this branch (5852175) was resolved by concatenating both sides of the conflict in apps/backend/src/routes/public.ts instead of merging them. The result does not parse, let alone type-check, so none of the validation listed in the PR description can be passing on the current head.

Reproduced locally on 5852175:

# typecheck
src/routes/public.ts(81,7): error TS1005: 'try' expected.
src/routes/public.ts(136,7): error TS1005: 'try' expected.
src/routes/public.ts(182,7): error TS1005: 'try' expected.
src/routes/public.ts(231,4): error TS1128: Declaration or statement expected.

# lint
src/routes/public.ts 81:6 error Parsing error: 'try' expected

# vitest
The symbol "CACHE_CONTROL_HEADER" has already been declared (public.ts:34:6)
Unexpected "catch" (public.ts:81:6)
  -> public.test.ts: 0 tests collected, suite fails to load

The PR note says the build is "blocked by existing unrelated TypeScript issues" — that is not accurate. The failures above are caused by this branch's merge, not by pre-existing problems, and they are syntax errors, not type nits.

Must fix (blocking)

  1. public.ts: redo the merge by hand. Every handler now contains the new code, a duplicated copy of the old code that is unreachable after a return, and a second catch block — that is what produces the 'try' expected errors at lines 81, 136, 182. Duplicated import * as publicService (lines 3 & 9) and duplicated const CACHE_CONTROL_HEADER (lines 21 & 34) also need to collapse to one each.
  2. Get tsc --noEmit, eslint, and vitest green and re-run the commands in the PR description before re-requesting review.

Should fix

  1. The client-side OG meta tags will not be seen by any social scraper. Slack/Twitter/Facebook/Discord/WhatsApp crawlers do not execute JavaScript; they read the initial HTML response. Injecting og:* / twitter:* via a React useEffect (ProfilePage.tsx) means the rich preview this PR is built for never renders for those bots. The backend image endpoint is fine, but the tags pointing at it need to be server-rendered (SSR / prerender / a meta-injecting middleware on the profile route). As written, the feature does not achieve its stated goal.
  2. fetchAvatarBase64 SSRF guard is incomplete and unbounded. Requiring https:// does not prevent SSRF — https://169.254.169.254/..., https://localhost, and https://10.0.0.x are all still fetched server-side. There is also no response-size cap, so a malicious avatar URL can stream an arbitrarily large body into memory via arrayBuffer(). See inline comment.

Nits

  1. The OG route queries app.prisma.user.findUnique directly, while every other handler in this file goes through publicService. Inconsistent; consider moving it behind the service for testability and parity.
  2. buildMetaDescription counts platforms via profile.links.length, but the image counts _count.platformLinks. These can disagree (links shown vs total connected).

The OG image generation itself (og-image.ts SVG template, XML escaping, hex sanitisation, initials fallback, fire-and-forget cache write, the test coverage) is solid work. The blocker is purely the broken merge — fix that and most of this is mergeable.

Comment thread apps/backend/src/routes/public.ts
Comment thread apps/backend/src/routes/public.ts Outdated
Comment thread apps/backend/src/routes/public.ts Outdated
Comment thread apps/backend/src/utils/og-image.ts Outdated
Comment thread apps/web/src/pages/ProfilePage.tsx Outdated
@amritbej

Copy link
Copy Markdown
Contributor Author

@Harxhit ,
i have made the changes please review it ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend gssoc:approved Required label for every approved PR. Gives the base +50 points and enables contribution tracking. web

Projects

None yet

Development

Successfully merging this pull request may close these issues.

backend + web: implement permanent shareable public profile page with OG meta tags

3 participants